import { httpError, Inject, Provide } from '@midwayjs/core'
import { Context } from '@midwayjs/koa'
import { InjectEntityModel } from '@midwayjs/typeorm'
import { In, Repository } from 'typeorm'

import { DeleteDTO } from '@/dto'
import { SysPostEntity } from '@/entity'
import { StateService } from '@/service'

import { CreatePostDTO, FindPostPageDTO, UpdatePostDTO } from './post.dto'

@Provide()
export class PostService {
  @Inject()
  ctx: Context

  @InjectEntityModel(SysPostEntity)
  postModel: Repository<SysPostEntity>

  async handleCreate(dto: CreatePostDTO) {
    const stateService = await this.ctx.requestContext.getAsync(StateService)

    const jwtPayload = stateService.getJwtPayload()

    const newPost = new SysPostEntity()

    Object.assign<any, any, Partial<SysPostEntity>>(newPost, dto, {
      createBy: jwtPayload.userName
    })

    await this.postModel.save(newPost)
  }

  async handleUpdate(id: string, dto: UpdatePostDTO) {
    const stateService = await this.ctx.requestContext.getAsync(StateService)

    const jwtPayload = stateService.getJwtPayload()

    const post = await this.postModel.findOne({ where: { postId: id } })

    if (!post) {
      this.ctx.throw(new httpError.BadRequestError('岗位不存在'))
    }

    Object.assign<any, any, Partial<SysPostEntity>>(post, dto, {
      updateBy: jwtPayload.userName
    })

    await this.postModel.save(post)
  }

  async handleFindPage(dto: FindPostPageDTO) {
    const { pageNum, pageSize, ...where } = dto

    const [list, total] = await this.postModel.findAndCount({
      where: {
        ...where
      },
      order: {
        postSort: 'ASC'
      },
      take: pageSize,
      skip: (pageNum - 1) * pageSize
    })

    return {
      pageNum,
      pageSize,
      total,
      list
    }
  }

  async handleDelete(dto: DeleteDTO) {
    const { ids } = dto

    const list = await this.postModel.find({
      relations: { users: true },
      where: { postId: In(ids) }
    })

    for (const post of list) {
      post.users = []

      await this.postModel.save(post)
    }

    await this.postModel.delete(ids)
  }
}
